#ifndef _MAIL_MANANGER_H_
#define _MAIL_MANANGER_H_

#include "Common.h"
#include "Resource.h"
#include "ResourceManager.h"
#include "Singleton.h"
#include "String.h"
#include "Mails.h"
#include "NGLog.h"

typedef struct game_friends_tag_
{

/* !#AUTO DATABASE TABLE GAME_FRIENDS ST_DEF */
	
		/* '好友id'*/
		uint32 	friend_id;
		/* '服务器组id'*/
		uint32 	group_id;
		/* '好友类型 1 平台好友类型  2 游戏好友类型'*/
		uint32 	type;
		/* '好友标志 0x1 正常 0x02 忽略聊天信息 0x04 忽略邮件信息'*/
		uint32 	flag;
		/* '好友状态 0 未知状态 1 一般状态 2 好友请求状态 3 拒绝添加状态 4 删除状态'*/
		uint32 	status;
		/* '好友分组'*/
		uint32 	category;
		/* '游戏分区id'*/
		int32 	gz_id;
		/* '好友游戏分区id'*/
		int32 	friend_gz_id;
		/* '用户id'*/
		uint32 	user_id;
		/* '用户平台id'*/
		int32 	user_pid;
		/* '好友用户id'*/
		uint32 	friend_user_id;
		/* '好友pid'*/
		int32 	firend_pid;
		/* '用户客户id'*/
		String 	friend_client_id;
		/* '好友君主外貌id'*/
		uint32 	id;
		/* '好友君主头像id'*/
		uint32 	icon;
		/* '头像链接'*/
		String 	icon_url;
		/* '好友名'*/
		String 	name;
		/* '好友备注名'*/
		String 	nick;
		/* '好友描述'*/
		String 	desc;
		/* '用户自定义数据'*/
		String 	user_data;
		/* '好友添加时间（秒数)'*/
		uint32 	create_time;
		/* '最后登录时间'*/
		uint32 	active_time;
		/* '无符号整形数据1'*/
		uint32 	data1;
		/* '无符号整形数据2'*/
		uint32 	data2;
		/* '无符号整形数据3'*/
		uint32 	data3;
		/* '无符号整形数据4'*/
		uint32 	data4;
		/* '无符号整形数据5'*/
		uint32 	data5;
		/* '无符号整形数据6'*/
		uint32 	data6;
		/* '无符号整形数据7'*/
		uint32 	data7;
		/* '无符号整形数据8'*/
		uint32 	data8;
		/* '符号整形数据9'*/
		int32 	data9;
		/* '符号整形数据10'*/
		int32 	data10;
		/* '符号整形数据11'*/
		int32 	data11;
		/* '符号整形数据12'*/
		int32 	data12;
		/* '浮点数据1'*/
		float 	fdata1;
		/* '浮点数据2'*/
		float 	fdata2;
		/* '浮点数据3'*/
		float 	fdata3;
		/* '浮点数据4'*/
		float 	fdata4;
		/* '字符串数据1'*/
		String 	sdata1;
		/* '字符串数据2'*/
		String 	sdata2;
		/* '字符串数据3'*/
		String 	sdata3;
		/* '字符串数据4'*/
		String 	sdata4;
		/* '字符串数据5'*/
		String 	sdata5;
		/* '字符串数据6'*/
		String 	sdata6;
		/* '字符串数据7'*/
		String 	sdata7;
		/* '字符串数据8'*/
		String 	sdata8;
		/* '64位无符号整形数据1'*/
		uint64 	idata1;
		/* '64位无符号整形数据2'*/
		uint64 	idata2;
		/* '64位整形数据1'*/
		int64 	idata3;
		/* '64位整形数据2'*/
		int64 	idata4;
		/* '双精度浮点数据1'*/
		double 	ddata1;
		/* '双精度浮点数据2'*/
		double 	ddata2;
		/* '双精度浮点数据3'*/
		double 	ddata3;
		/* '双精度浮点数据4'*/
		double 	ddata4;
/* #END DATABASE */
}GameFriend;

typedef struct friend_category_tag_
{

/* !#AUTO DATABASE TABLE FRIEND_CATEGORY ST_DEF */
	
		/* '好友分组表'*/
		uint32 	cate_id;
		/* '分组的服务器id'*/
		uint32 	group_id;
		/* '分组的用户id'*/
		uint32 	user_id;
		/* '用户平台id'*/
		uint32 	user_pid;
		/* '组名'*/
		String 	name;
		/* '描述'*/
		String 	desc;
		/* '创建时间'*/
		uint32 	create_time;
		/* '标志 （未用）'*/
		uint32 	flag;
		/* '状态 0 无效状态 1  一般状态 2 删除状态'*/
		uint32 	status;
		/* '整形数据1'*/
		uint32 	data1;
		/* '整形数据2'*/
		uint32 	data2;
		/* '整形数据3'*/
		int32 	data3;
		/* '整形数据4'*/
		int32 	data4;
		/* '浮点数据1'*/
		float 	fdata1;
		/* '浮点数据2'*/
		float 	fdata2;
		/* '字符串数据1'*/
		String 	sdata1;
		/* '字符串数据2'*/
		String 	sdata2;
/* #END DATABASE */
}FriendGroup;

typedef struct game_report_tag_
{

/* !#AUTO DATABASE TABLE GAME_REPORT ST_DEF */
		/* '报告id'*/
		uint32 	report_id;
		/* '报告组id'*/
		uint32 	group_id;
		/* '报告状态 0 无效状态 1 报告创建 2 报告已读 255 报告数据删除'*/
		uint32 	status;
		/* '报告类型  0 无效报告 1 战斗报告 2 内政报告 3 事件报告'*/
		uint32 	type;
		/* '玩家序列号'*/
		uint32 	user_id;
		/* '报告创建时间'*/
		uint32 	create_time;
		/* '报告阅读时间'*/
		uint32 	read_time;
		/* '报告标题'*/
		String 	title;
		/* '内容类型 0 无效内容 1 文本内容 2 xml内容 3 html 内容'*/
		uint32 	content_type;
		/* '报告内容'*/
		String 	content;
/* #END DATABASE */
}GameReport;





class  MailManager: public ResourceManager,public Singleton<MailManager>
{
public:
	//默认的好友分组
	enum  FriendGroupDef
	{
		FriendGroupNone			= 0,	//无效的好友分组
		FriendGroupNormal		= 1,	//我的好友
		FriendGroupBlacklist		= 2,	//黑名单
		FriendGroupSystem		= 3,	//系统分组
		FriendGroupNotice		= 4	//通告目录 用于存放临时存放 请求的好友信息等
	};
	
	enum FriendStatus
	{
		FriendStatusNone		= 0,	//无效的状态
		FriendStatusNormal		= 1,	//一般状态
		FriendStatusReq			= 2,	//好友添加邀请状态
		FriendStatusDeny		= 3,	//好友拒绝添加状态
		FriendStatusDeleted		= 255	//删除状态
	};

	enum FriendFlag
	{
		FriendFlagNone			= 0x00,  //无效标志位
		FriendFlagNormal		= 0x01,	//一般标志位
		FriendFlagIgnChar		= 0x02,	//聊天无视
		FriendFlagIgnMail		= 0x04	//邮件无视
	};

	enum FriendGroupStatus
	{
		FriendGroupStatusNone		= 0,	//无效状态
		FriendGroupStatusNormal		= 1,	//一般状态
		FriendGroupStatusDeleted	= 255	//删除状态
	};

	enum ReportStatus
	{
		ReportStatusNone		= 0,	//无效状态
		ReportStatusCreate		= 1,	//报告创建
		ReportStatusRead		= 2,	//报告已读 
		ReportStatusDeleted		= 255	//报告数据删除
	};

	enum ReportType
	{
		ReportTypeNone			= 0,	//无效报告类型
		ReportTypeBattle		= 1,	//战斗报告
		ReportTypeOrder			= 2,	//指令报告
		ReportTypeEvent			= 3	//事件报告
	};

	enum ReportContentType
	{
		ReportContentTypeNone		= 0,	//无效的内容类型
		ReportContentTypeText		= 1,	//文本内容
		ReportContentTypeXML		= 2,	//XML文本内容
		ReportContentTypeHTML		= 3	//HTML文本内容
	};

public:
	MailManager();
	~MailManager();

	String	getMailStringName(const uint32 & serial);
	
	ResourcePtr  create(const uint32 & serial,const NameValuePairList* params = 0);
	ResourceCreateOrRetrieveResult  \
		createOrRetrieve(const uint32 & serial,const NameValuePairList* params = 0);
	ResourcePtr  load(const uint32 & serial);
	ResourcePtr     reload(ResourceHandle handle);

	//user manager start
	void	Startup(const uint32 & gid,bool isBattle = true);
	void 	Shutdown(void);

	//用于得到一个Mail结构，用于向数据库追加新效果的记录
	Resource * newDumyMail(void);
	void	freeDumyMail(Resource * dumy);

	//根据模板向数据库插入新的记录，返回插入的记录
	ResourcePtr	createMailDatabase(Resource * dumy);
	ResourcePtr	loadMailDatabase(Resource * dumy);

	//根据查询，返回符合条件的记录 offset 为翻页起点 limitcount 为取回邮件最大数量 query 为查询条件在 WHERE之后
	bool	getMailList(std::list<MailPtr> * mails,const uint32 & offset,const uint32 & limitcount,const char * query,...);

	//根据查询条件返回一个查询结果数量 query 为在WHERE之后的SQL语句
	uint32	getDBCount(const char * query,...);

	//好友和好友分组管理函数
        GameFriend  * newDumyFriend(void);
        void    freeDumyFriend(GameFriend * dumy);

	//根据结构添加好友信息，返回0表示添加失败，成功返回friend_id 
	uint32  addFriendDB(GameFriend * fri);
	//根据结构，更新好友信息数据库
	bool	updateFriendDB(GameFriend * fri);
	//根据好友ID,数据库删除好友
	bool	deleteFriendDB(const uint32 & friend_id);
	//根据好友ID，得到好友信息
	bool  getFriend(const uint32 & friend_id,GameFriend * fri);

	//根据查询条件，返回一个查询结果
	bool	getFriendList(std::list<GameFriend> * friends,const uint32 & offset,const uint32 & limitcount,const char * query,...);
	//更加查询条件 返回好友查询数量
	uint32 getFriendDBCount(const char * query,...);

	//分组管理信息
	FriendGroup *  newDumyFriendGroup(void);
        void    freeDumyFriendGroup(FriendGroup * dumy);

	uint32 addFriendGroupDB(FriendGroup * grp);
	bool	updateFriendGroupDB(FriendGroup * grp);
	bool	deleteFriendGroupDB(const uint32 & cate_id);
	bool	getFriendGroup(const uint32 & cate_id,FriendGroup * grp);

	bool  getFriendGroupList(std::list<FriendGroup> * groups,const uint32 & offset,const uint32 & limitcount,const char * query,...);
	uint32 getFriendGroupDBCount(const char * query,...);

	//报告和报告分组管理函数
	GameReport *  newDumyReport(void);
	void	freeDumyReport(GameReport * dumy);

	//根据结构添加报告信息，返回0表示添加失败，成功返回report_id 
	uint32  addReportDB(GameReport * report);
	//根据结构，更新报告信息数据库
	bool	updateReportDB(GameReport * report);
	//根据报告ID,数据库删除报告
	bool	deleteReportDB(const uint32 & report_id);
	//根据报告ID，得到报告信息
	bool  getReportDB(const uint32 & report_id,GameReport * report);

	//根据查询条件，返回一个查询结果
	bool	getReportList(std::list<GameReport> * reports,const uint32 & offset,const uint32 & limitcount,const char * query,...);
	//更加查询条件 返回报告查询数量
	uint32 getReportDBCount(const char * query,...);



	ResourcePtr   newDBObject(void);
	ResourcePtr   getDBObjectByHandle(const uint32 & handle);
	bool	getDBObjects(std::list<ResourcePtr> * objs,const uint32 & offset,const uint32 & limitcount,const char * query,...);


	
	//后台处理邮件程序
	bool	background();
	const bool & isBattleServer(void)	{	return m_battle_server;	}
protected:
	uint32		m_default_gid;
	String		m_default_group;
	bool		m_server_run;
	bool		m_battle_server;
       /// @copydoc ResourceManager::createImpl
        Resource* createImpl(const String& name, ResourceHandle handle,
            const String& group, bool isManual, ManualResourceLoader* loader,
            const NameValuePairList* createParams);
};


//后台自动清除未使用的邮件对象
class MailBackgroundThread : public ThreadBase
{
        MailManager  * mm;
public:
       	MailBackgroundThread(MailManager * s) :ThreadBase("MailBackgroundThread"),mm(s) {}
        bool run()
        {
                Log.Success("Mail Backgound Thread","Mail background process thread start.");
                return mm->background();
        }
};



#define   sMailMgr   MailManager::getSingleton()



#endif
